const Koa = require('koa')
// 用来创建子进程，自动打开浏览器
const cp = require('child_process')
const koaBody = require('koa-body')
const bodyParser = require('koa-bodyparser')
const logger = require('koa-logger')

const session = require('koa-session')
const CSRF = require('koa-csrf')
const app = module.exports = new Koa();

const views = require('koa-views')
const path = require('path')

//全局变量配置信息
let message = require("./utils/config").message

//配置视图 这个必须放在 router 前面
app.use(views(path.join(__dirname, './views'), {
  extension: 'ejs'
}))

//设置路由
const users = require('./routes/users')
const indexRoutes = require('./routes/index')
const listRoutes = require('./routes/list')
const listUsers = require('./routes/rest/listUsers')
const getUserDetailByID = require('./routes/rest/getUserDetailByID')
const deleteUserByID = require('./routes/rest/deleteUserByID')
const addUser = require('./routes/rest/addUser')
const mysqlAsync = require('./routes/mysqlAsync')
const restApi = require('./routes/restApi')
const mysqlQueryAsync = require('./routes/mysql/mysqlQueryAsync')
//const mysqlInsertAsync = require('./routes/mysql/mysqlInsertAsync')
const getPublicIp = require('./routes/getPublicIp')
const upload = require('./routes/upload')
const post = require('./routes/post')
const readFileAsync = require('./routes/readFileAsync')
const readFileSync = require('./routes/readFileSync')
const error500 = require('./routes/error')

//设置静态资源 html，css，img 等
//这里使用 ejs 模版，就不用 静态 html 了
/* const static = require('koa-static')
app.use(static('./public'))
app.use(static('./public/html')) */

//上传设置
app.use(koaBody({ multipart: false }))
app.use(bodyParser())

// 跨域设置 这里是全开放啊，实际是不能这样子的
/* app.use(async (ctx, next) => {
  ctx.set("Access-Control-Allow-Origin", "*")
  ctx.set("Access-Control-Allow-Headers", "X-Requested-With")
  ctx.set("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS")
  ctx.set("X-Powered-By", 'wzh')
  //ctx.set("Content-Type", "application/json;charset=utf-8")
  await next()
}) */

//设置 session
app.keys = ['wwzzhh20190911', " I dont know"]
const sessionConfig = require("./utils/config").sessionConfig
app.use(session(sessionConfig, app))

// add the CSRF middleware
app.use(new CSRF({
  invalidTokenMessage: 'Invalid CSRF token',
  invalidTokenStatusCode: 403,
  excludedMethods: ['GET', 'HEAD', 'OPTIONS'],
  disableQuery: false
}))
//app.use(new CSRF())

//页面都要求验证登录
app.use(async (ctx, next) => {
  users.localFilter(ctx)
  await next()
}
)
//app 使用以上设置的路由
app.use(users.routes())
//首页 / 或 /index
app.use(indexRoutes.routes())
app.use(listRoutes.routes())
app.use(listUsers.routes())
app.use(getUserDetailByID.routes())
app.use(deleteUserByID.routes())
app.use(addUser.routes())
app.use(mysqlAsync.routes())
app.use(restApi.routes())
app.use(mysqlQueryAsync.routes())
//app.use(mysqlInsertAsync.routes())
app.use(getPublicIp.routes())
app.use(upload.routes())
app.use(post.routes())
app.use(readFileAsync.routes())
app.use(readFileSync.routes())
app.use(error500.routes())

app.use(logger())
// logger
app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

// 挂载日志模块
app.use(async (ctx, next) => {
  ctx.util = {
    log: require('./utils/log')
  }
  await next()
})

//mysql 连接
app.use(async (ctx, next) => {
  const mysql = require('./utils/mysql')

  try {
    const results = await mysql.testMysql()
    message.mysql = "正常"
    console.log("mysql连接成功！")
  }
  catch (err) {
    console.error(err)
    message.mysql = "连接失败啦"
    console.error("mysql连接失败啦！")
  }
  await next()
})

//错误处理
app.use(async (ctx, next) => {
  console.log('ctx.status ===', parseInt(ctx.status))

  if (parseInt(ctx.status) == 404) {
    //忽略 favicon
    if (ctx.originalUrl == '/favicon.ico') return
    //记录日志
    ctx.util.log.info('错误：404', ctx.originalUrl)

    switch (ctx.accepts('html', 'json')) {
      case 'html':
        ctx.type = 'html'
        ctx.body = '<p>嗷嗷！您要访问的页面走丢了～～～</p>'
        break
      case 'json':
        ctx.body = {
          message: '嗷嗷！您要访问的页面走丢了 ～～～'
        }
        break
      default:
        ctx.type = 'text'
        ctx.body = '嗷嗷！您要访问的页面走丢了 ～～～'
        break
    }
  }

  await next()
})

// 自定义 500 错误页面
app.on('error', (err, ctx) => {
  if (process.env.NODE_ENV != 'test') {
    console.log('sent error %s', err.message)
    console.log(err)
  }

  console.log(err)
  ctx.body = err
  //记录日志 为什么这里的 ctx.util.log undefine ？ ctx 改变了？
  //ctx.util.log.info('系统错误：error', ctx.originalUrl)
  const log = require('./utils/log')
  log.info('系统错误 :页面 %s ,%s', ctx.originalUrl, err)
})

//app.listen(3000)
if (!module.parent) app.listen(3000)
// 自动打开浏览器
cp.exec('open http://localhost:3000/')

